﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq.Expressions;
using System.Data;
using Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace ef.DataBase
{
    public class DataContext : DbContext, IDataContext
    {
        #region Properties

        /// <summary>
        /// 得到UserBase结果集
        /// </summary>
        public IDbSet<UserBase> UserBases { get; private set; }
        /// <summary>
        /// 得到UserInfo结果集
        /// </summary>
        public IDbSet<UserInfo> UserInfos { get; private set; }
        /// <summary>
        /// 得到Category结果集
        /// </summary>
        public IDbSet<Category> Categorys { get; private set; }

        public IDbSet<User_Diary> User_Diarys { get; private set; }
        #endregion

        #region Constructors
        public DataContext()
            : this(DataConfig.GetConnectionString()) { }

        public DataContext(string cs)
            : base(cs)
        {
            UserBases = this.Set<UserBase>();
            UserInfos = this.Set<UserInfo>();
            Categorys = this.Set<Category>();
            User_Diarys = this.Set<User_Diary>();
            DataConfig.Init();//数据库与DBContext依附方式　

        }

        #endregion
        /// <summary>
        /// 数据库建立时执行
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            #region 设置字段的长度，是否为空等
            modelBuilder.Entity<UserBase>().Property(user => user.UserName).HasMaxLength(50).IsRequired();
            #endregion
            #region 设置实体外延属性是否反映到物理数据表中
       // modelBuilder.Entity<UserBase>().Ignore(user => user.User_Diary);
            //同时也关闭了延时加载EF是默认开启延迟加载，延迟加载的关系表中，必须建立表关系，也就是SQL的FK键。延迟加载非常好用，但存在性能问题，因为延迟加载关联到几个表，就要执行几次数据表查询，而不是一次性查询。这也是从字义上理解的达到一致。否则就属于贪婪加载，即Context上下文里的Include("实体名")，可以实现一次性一条SQL语句查询，但我奇怪的是Include的string参数为啥不是表名，反而是实体名却用字符串来传入。

           //  modelBuilder.Entity<UserBase>().Ignore(user => user.UserInfo);
            // modelBuilder.Entity<User_Diary>().Ignore(user => user.UserBase);
            // modelBuilder.Entity<UserInfo>().Ignore(user => user.UserBase);
            #endregion

            #region 设置主外键约束，同时可以开启延时加载

            #endregion
            // modelBuilder.Entity<Order>().ToTable("Order"); 和实体类名的Table特性设置相同

            // 移除EF的表名公约 
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            // 还可以移除对MetaData表的查询验证
            //modelBuilder.Conventions.Remove<IncludeMetadataConvention>();


        }

    }

}